<?php

define('BRUNCE_ADD_EVENT',         1);
define('BRUNCE_GET_STATUS',        2);

function brunce_getErrMsg($ierr)
{
	switch($ierr)
	{
		case 0 :   return "Success";
		case -2:   return "Key is not exist";
		case -1:   return "System error";
		case -3:   return "input args is error";
		default:   return "Undefined error: $ierr";
	}
}

class Brunce{
	var $sock;
        var $retry;
	function __construct($port = 5080, $retry = 1){
                $this->retry = $retry;
		$this->sock = @fsockopen("10.62.162.75", $port, $errno, $errstr);
		if (!$this->sock) {
			error_log("ERROR: $errno - $errstr");
			return;
		}
		stream_set_timeout($this->sock, 1, 300);
	} 

	function __destruct() {  fclose($this->sock);   unset($this->sock);     } 
	function graph( $user1, $user2){
		$ret = $this->inner_graph($user1, $user2); 
		$try = 0;
		while($ret === false && $try < $this->retry)
		{
			$ret = $this->inner_graph($user1, $user2); 
			$try++;
		}
		return $ret;
	}
	function friends( $user){
		$ret = $this->inner_friends($user); 
		$try = 0;
		while($ret === false && $try < $this->retry)
		{
			$ret = $this->inner_friends($user); 
			$try++;
		}
		return $ret;
	}
	function status($idx){
		$ret = $this->inner_status($idx ); 
		$try = 0;
		while(!is_array($ret)  && $try < $this->retry)
		{
			$ret = $this->inner_status( $idx); 
			$try++;
		}
		return $ret;
	}
	
	function event( $arr){
		if(is_array($arr) && sizeof($arr) > 0)
		{
			$isize = sizeof($arr); 
			$input = "P".pack("I", time(NULL)%4 + 1 )."\001";
			$input .= "y\001".pack("I",$isize);
			foreach($arr as $k=>$v)
				$input .= pack("I",strlen($k)).$k.pack("I", 1*$v);
			fwrite($this->sock, $input);
			$readlen = $READ = 1024;
			$response = fread($this->sock, $READ);
			return true;
		}
		return false;
	}
	function reset( $arr){
		if(is_array($arr) && sizeof($arr) > 0)
		{
			$isize = sizeof($arr); 
                        $input = "P".pack("I", time(NULL)%4 + 1 )."\002";
			$input .= "y\004".pack("I",$isize);
			foreach($arr as $k=>$v)
				$input .= pack("I",strlen($k)).$k;
			fwrite($this->sock, $input);
			return true;
		}
		return false;
	}
	function relation( $user1, $user2){
			$isize = sizeof($arr);
                        $input = "P".pack("I",intval($user1)%4+1 )."\002";
 			$input .= "y\005";
			$input .= pack("I",strlen($user1)).$user1.pack("I",strlen($user2)).$user2;
			fwrite($this->sock, $input);
			return true;
	}

	function inner_graph( $user1, $user2){
                        $input = "P".pack("I", intval($user1)%4 + 1 )."\001";
			$input .= "y\002";
			$input .= pack("I",strlen($user1)).$user1;
			$input .= pack("I",strlen($user2)).$user2;
			fwrite($this->sock, $input);
			$readlen = $READ = 102400;
			$response = fread($this->sock, $READ);
	                $arr = array();
              		if(isset($response{7}))
			{
				$sub = substr($response, 0, 8);
				$unpacked = unpack('I2',$sub);
				if(isset($unpacked['1']) && isset($unpacked['2']))
				{
					if($unpacked['2'] < 0)
                                        {
                                                error_log(brunce_getErrMsg($unpacked['2'])); 
                                                var_dump($unpacked);
                                                // var_dump($response);
						return $unpacked['2'];
					}
                                        $length = $unpacked['1'];
					$left = $unpacked['1'] - strlen($response);
					while ( $left > 0 && !feof($this->sock) )
					{
                                                echo "read continue $left <BR>";
						$contstr = fread ( $this->sock,  $READ );
						if ( $contstr )
						{
							$response .= $contstr;
							$left -= strlen($contstr);
						}
					}

                                        //return errorcode;
					//echo "read = "; var_dump($response);
					$idx = 8;
					$sub = substr($response, $idx , 4);
					if(!isset($sub{3}))
					{
						error_log("get depth data error!");
						return false;
					}

					$unpacked = unpack('I',$sub);
					$idx += 4;
					$depth = $unpacked['1'];
                                        if($depth == 0)
						return true;
					$sub = substr($response, $idx , 4);
					if(!isset($sub{3})){
						echo "length = $length;  depth =  "; var_dump($unpacked);
						error_log("get items counts data error");
						return false;
					}

					$unpacked = unpack('I',$sub);
                                        $items = $unpacked['1'];
					$idx += 4;
                                       // $direct = $response[$idx];
                                       // $idx += 1;
					for($j = 0; $j<$items ; $j++)
					{
						$subarr = array();
						for($i=0; $i<$depth; $i++)
						{
                                                        if($idx >= $length)
                                                        { var_dump($arr);     break; }
							$str = substr($response, $idx, 4);
							if(strlen($str) < 4){
                                                         // var_dump($response);
                                                         var_dump($idx);
                                                         var_dump($str);
								error_log("get one line friends data error");
								return false;
							}

							$unpacked = unpack('Iint', $str);
							$idx += 4;
							$subarr[$i] = substr($response, $idx, $unpacked['int']);
							$idx += $unpacked['int'];
						}
						if(sizeof($subarr) >= $depth)
							$arr[$j] = $subarr;
                                                else
                                                   return false;
					}
                                        if(sizeof($arr) <= 0) // $items)
                                              return false;
				}
			}
			else
				return false; //echo "return error!";
			return $arr;
	}
	function inner_friends( $user){
   $input = "P".pack("I", intval($user)%4 + 1 )."\001";
			$input .= "y\003";
			$input .= pack("I",strlen($user)).$user;
			fwrite($this->sock, $input);
			$readlen = $READ = 102400;
                  	$response = fread($this->sock, $READ);
//var_dump($response); echo "<BR>";
	                $arr = array();
              		if(isset($response{7}))
			{
				$sub = substr($response, 0, 8);
				$unpacked = unpack('I2',$sub);
				if(isset($unpacked['1']) && isset($unpacked['2']))
				{
					if($unpacked['2'] < 0)
					{
                                                error_log(brunce_getErrMsg($unpacked['2']));
                                                var_dump($unpacked);
                                        //        var_dump($response);    
                                        	return $unpacked['2']; // return errorcode;
					}
                                        //  var_dump($unpacked);
                                        $left = $unpacked['1'] - strlen($response);
					while ( $left > 0 && !feof($this->sock) )
					{
 echo "read continue $left <BR>";
						$contstr = fread ( $this->sock, $READ );
						if ( $contstr )
						{
							$response .= $contstr;
							$left -= strlen($contstr);
						}
					}

					//echo "read = "; var_dump($response);
					$idx = 8;
					$sub = substr($response, $idx , 4);
					if(!isset($sub{3})){
						error_log("get friends counts data error!");
						return false;
					}

					$unpacked = unpack('I',$sub);
					//echo "counts = "; var_dump($unpacked);
					$idx += 4;
					$counts = $unpacked['1'];
                                       // echo "f counts = $counts";
					if($counts == 0)
						return $arr;
					for($j = 0; $j<$counts ; $j++)
					{
						$str = substr($response, $idx, 4);
						if(!isset($str{3})){
							error_log("get firends name length data error");
							return false;
						}
						$unpacked = unpack('Iint', $str);
						$idx += 4;
						$uname = substr($response, $idx, $unpacked['int']);
						$idx += $unpacked['int'];
                                        	$str = substr($response, $idx, 4);
						if(!isset($str{3})){
							error_log("get active number error!");
							return false;
						}
						$unpacked = unpack('Iint', $str);
						$idx += 4;
                                                $arr[$uname] = $unpacked['int']; 
					}
                                        if(sizeof($arr) < $counts)
                                           return false;
				}
			}
			else
				return false; //echo "return error!";
//echo "friends size=".sizeof($arr);
			return $arr;
	}
	function inner_status($idx){
   $input = "P".pack("I", $idx%4 + 1 )."\001";
			$input .= "y\006status";
			fwrite($this->sock, $input);
			$readlen = $READ = 1024;
			$response = fread($this->sock, $READ);
			$arr = array();
			if(isset($response{7}))
			{
				$sub = substr($response, 0, 8);
				$unpacked = unpack('I2',$sub);
				if(isset($unpacked['1']) && isset($unpacked['2']))
				{
					if($unpacked['2'] != 0)
						return false; // return errorcode;
				//	echo "read = "; var_dump($response);
					$idx = 8;
					$sub = substr($response, $idx , 12);
                                        if(!isset($sub{11}))
                                            return false;
					$arr = unpack('I3',$sub);
				}
			}
			else
				return false; //echo "return error!";
			return $arr;
	}



}


?>
